package com.ipharma.application.services;

import java.rmi.RemoteException;
import java.sql.Timestamp;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import com.ipharma.McdError;
import com.ipharma.McdPrs;
import com.ipharma.beans.Helper;
import com.ipharma.config.Config;
import com.ipharma.config.Session;
import com.ipharma.dto.Task;
import com.ipharma.model.ContenidoDispenser;
import com.ipharma.model.Producto;
import com.ipharma.model.Tarea;
import com.ipharma.service.DispenserService;
import com.ipharma.service.ServiceException;

/**
 * A TaskList class.
 * <P>
 * 
 * @author JorgE.H
 */
public class TaskList extends Object {

   /**
    * Attributes
    */
   DispenserService dispenserService; 

   Session theSess;

   Vector vTasks;

   int dispId;

   /**
    * Constructor
    * 
    * @param pId
    *           the dispenser id
    */
   public TaskList(Session pSess) {

      try {
         theSess = pSess;
         Config config = (Config) theSess.get(McdPrs.CONFIG);
         dispId = Integer.parseInt(config.getDispenser());
         dispenserService = Helper.getDispenserService();
      } catch (Exception e) {
         McdError.add(e);
      }
   }

   /**
    * Returns a vector with current dispenser tasks in DB
    * 
    * @return a Vector with Tasks
    */
   public Vector getTasks() throws Exception {

      List l_rs;
      vTasks = new Vector();

      // reads products of current dispenser from DB
      l_rs = dispenserService.findTareasDe(new Long(dispId), "");
      for (Iterator iter = l_rs.iterator(); iter.hasNext();) {
         Tarea tarea = (Tarea) iter.next();
         String ls_done = tarea.getOk();
         boolean done = true;
         if (ls_done != null)
            done = ls_done.toUpperCase().equals(McdPrs.D_YES);
         Producto producto = tarea.getDispenserLoteProducto().getLoteProducto()
               .getProducto();
         String description = producto.getDescripcion();
         String code = producto.getCodigo();
         String origin = tarea.getFuente();
         Integer batchNumber = tarea.getDispenserLoteProducto()
               .getLoteProducto().getNroLote();
         Long prodId = producto.getId();
         Long taskId = tarea.getId();
         Integer quantity = tarea.getCantidad();
         Task l_task = new Task(description, code, prodId.intValue(), taskId
               .intValue(), batchNumber.intValue(), quantity.intValue(),
               origin, done);

         // fills a vector with Product objects
         vTasks.add(l_task);
      }

      // returns the vector
      return vTasks;
   }

   /**
    * Updates completed tasks to DB
    * 
    * @return a vector of tasks done
    */
   public Vector setTasks() {

      Task l_task;
      Vector lv_done = null;

      try {
         for (int i = 0; i < vTasks.size(); i++) {
            l_task = (Task) vTasks.elementAt(i);
            if (l_task.isDone()) {
               if (lv_done == null)
                  lv_done = new Vector();
               lv_done.add(l_task);
               // updates task status
               Tarea tarea = new Tarea();
               tarea.setId(new Long(l_task.getTaskId()));
               tarea.setFechaModificacion(new Timestamp(System.currentTimeMillis()));
               tarea.setFuente(l_task.getOrigin());
               tarea.setOk(l_task.getDone());
               tarea.setCantidad(new Integer(l_task.getQuantity()));

               dispenserService.updateTarea(new Long(dispId), new Integer(l_task
                     .getBatchNumber()), new Long(l_task.getProdId()), tarea);

               // updates stock according to task orders
               perform(l_task);
            }
         }
      }  catch (ServiceException se) {
         McdError.add(se);
      } catch (RemoteException e) {
         e.printStackTrace();
         McdError.add(e);
      }
      return lv_done;
   }

   /**
    * Performs task updating corresponding stocks
    */
   public void perform(Task pTask) {

      int li_qty, li_qty2;
      try {
         // when updating stocks, products should be fit in left to right
         // fashion into dispenser position
         // according to dct_priority field.
         System.out.println("performing task " + pTask.getTaskId()
               + " for product " + pTask.getDescription());
         // gets remaining sotck in dispenser
         li_qty = dispenserService.getProductStock(new Long(dispId), 
                                                   new Long(pTask.getProdId())).intValue();
         // adds quantity recharged
         li_qty += pTask.getQuantity();
         // gets positions of those products
         List l_rs = dispenserService.getAllPositions(new Long(dispId), 
                                                      new Long(pTask.getProdId()));

         // re-accomodates products in left to right fashion
         int li_newQty = 0;
         for (Iterator iter = l_rs.iterator(); iter.hasNext();) {
            ContenidoDispenser contenido = (ContenidoDispenser) iter.next();
            int li_capacity = contenido.getCapacidad().intValue();
            String ls_row = contenido.getFila().toString();
            String ls_col = contenido.getColumna().toString();

            li_qty2 = li_qty - li_capacity;
            li_newQty = (li_qty2 > 0) ? li_capacity : li_qty;
            li_qty = (li_qty2 > 0) ? li_qty2 : 0;

            // updates database
            dispenserService.updateContenidoDispenser(new Long(dispId), ls_row, ls_col,
                                                      new Integer(li_newQty));
         }

         // updates product stock in dispenser_product_batchs
         dispenserService.updateBatchStock(new Long(dispId), new Long(pTask.getProdId()),
               new Integer(pTask.getBatchNumber()), new Integer(pTask.getQuantity()));
      } catch (RemoteException e) {
         McdError.add(e);
         e.printStackTrace();
      } catch (ServiceException e) {
         McdError.add(e);
         e.printStackTrace();
      }
   }
   /** * end ** */
}